﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

using com.ReinforceLab.AudioModem;
using com.ReinforceLab.AudioModem.FSK;

namespace WpfApplication1
{
    /// <summary>
    /// TerminalWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class TerminalWindow : Window
    {
        const int baudRate = 1200;        
        FSKModem _modem;
        RawDataPacketSource _packetSource;
        IAudioPHY _phy;
        
        public TerminalWindow()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(TerminalWindow_Loaded);
        }
        
        void TerminalWindow_Loaded(object sender, RoutedEventArgs e)
        {
            _packetSource = new RawDataPacketSource();
            _modem = new FSKModem(BaudRate.B1200, _packetSource);
            _phy = new OpenALSocket(_modem.SamplingRate);            
            _modem.Start(_phy);

            Unloaded += new RoutedEventHandler(TerminalWindow_Unloaded);
        }

        void TerminalWindow_Unloaded(object sender, RoutedEventArgs e)
        {            
            _modem.Dispose();
        }

        void sendText()
        {
            if (String.IsNullOrEmpty(_inputTextBox.Text))
                return;

            byte[] data = Encoding.ASCII.GetBytes(_inputTextBox.Text + "\n");
            _packetSource.Write(data);

            _inputTextBox.Text = string.Empty;
        }

        void _timer_Tick(object sender, EventArgs e)
        {
            var buf = _packetSource.Read();
            if (buf.Length <= 0)
                return;

            var str = Encoding.ASCII.GetString(buf);
            if (!String.IsNullOrEmpty(str))
            {
                _terminalTextBox.Text = _terminalTextBox.Text + str;
            }            
        }

        private void inputTextSendButton_Click(object sender, RoutedEventArgs e)
        {
            sendText();
        }

        private void inputTextClearButton_Click(object sender, RoutedEventArgs e)
        {
            _inputTextBox.Text = string.Empty;
        }

        private void terminalTextClearButton_Click(object sender, RoutedEventArgs e)
        {
            _terminalTextBox.Text = string.Empty;
        }

        private void _inputTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {            
            //sendText();
        }

        private void _testButton_Click(object sender, RoutedEventArgs e)
        {
            //com.ReinforceLab.SignalTrace.TracerFactory.StartRecording();
            
            //var data = ASCIIEncoding.ASCII.GetBytes("test");
            var data = ASCIIEncoding.ASCII.GetBytes("T");
            /*
            byte[] data = new byte[1024 * 16];
            var rnd = new Random();
            for (int i = 0; i < data.Length; i++)
            {
                //data[i] = (byte)rnd.Next(255);
                data[i] = 0xa5;
            }
            */
            _packetSource.Write(data);            
            
            System.Threading.Thread.Sleep(1000);
            /*
            com.ReinforceLab.SignalTrace.TracerFactory.StopRecording();
            // dump
            com.ReinforceLab.SignalTrace.TracerFactory.DumpSpiceTr0(@"c:\bpsk_test.tr0");
            com.ReinforceLab.SignalTrace.TracerFactory.DumpCSV(@"c:\bpsk_test.csv");
            com.ReinforceLab.SignalTrace.TracerFactory.Clear(); */
        }

        private void _toneButton_Click(object sender, RoutedEventArgs e)
        {
            if (null != _modem)
            {
                _modem.Dispose();
                _modem = null;
            }

            if (_phy.IsRunning)
                _phy.Stop(true);

            // create tone
            var toneSource = new ToneSignalSource(_phy, 440, short.MaxValue);
            _phy.Start(toneSource);
        }
    }
}
